<template>
	<view class="flex items-center tabbox">
		<view class="relative flex-1  h100">
			<scroll-view 
				:id="`scroll-view${uid}`" 
				:scroll-left="scrollViewSlideDistance" 
				scroll-with-animation 
				:scroll-x="scroll ? true : false"
				style="white-space: nowrap" 
				class="w100 h100"
			>
				<view class="w100 h100 flex flex-column justify-center -ml-30" style="position: relative">
					<view class="mb-15 w100" :class="{ flex: !scroll }">
						<block v-for="(item, index) in list" :key="index">
							<view 
								@click="clickBlockEvent(index)" 
								style="transition: all ease .3s;"
								class="block-item px-30 text-24 inline-block"
								:class="{ 'text-primary text-32 font-weight-700': currentIndex === index }"
							>
								{{ item[name] }}
							</view>
						</block>
					</view>
					
					<view class="mb-15 h100" :class="{ flex: !scroll }" style="position: absolute;opacity: 0;z-index: -1">
						<block v-for="(item, index) in list" :key="index">
							<view class="new-block-item px-30 text-24 inline-block font-weight-700 text-primary text-32">
								{{ item[name] }}
							</view>
						</block>
					</view>
					
					<view 
						:style="{ width:`${currentBlockWidth}px`, marginLeft: `${blockSlideDistance}px` }" 
						style="transition: all ease .3s; " class="flex justify-center items-center relative"
					>
						<view class="w-20 h-5 round-full bgc-primary" />
					</view>
				</view>
			</scroll-view>
		</view>
		
		<view class="ml-30" v-if="$slots.right">
			<slot name="right" />
		</view>
	</view>
</template>

<script setup>
	import { ref, watch, getCurrentInstance, onMounted, computed } from "vue"
	import _ from "lodash"

	const { ctx, uid } = getCurrentInstance()
	const props = defineProps({
		modelValue: { type: Number, default: 0 },
		list: { type: Array, default: () => ([]) },
		name: { type: String, default: 'name' },
		scroll: { type: Boolean, default: true },
	})

	// 事件
	const emit = defineEmits(['update:modelValue', 'changeEvent'])
	const { currentIndex, currentBlockWidth, clickBlockEvent, blockSlideDistance, scrollViewSlideDistance } = useTabState()

	function useTabState() {
		// 当前下标索引
		const currentIndex = ref(0)

		//滑块列表
		const blockList = ref([])  // 初始的宽度
		const newBlockList = ref([])  // 全选中后宽度

		//当前滑块的宽度
		const currentBlockWidth = computed(() => blockList.value[currentIndex.value]?.width ?? 0)

		//滑块滑动距离
		const blockSlideDistance = computed(() => {
			const list = [...blockList.value]
			list.splice(currentIndex.value, 1, newBlockList.value[currentIndex.value])
			const blockListTemp = list.splice(0, currentIndex.value)
			return (blockListTemp.length ? blockListTemp.map(item => item?.width).reduce((a, b) => a + b) : 0)
		})

		//scrollView宽度
		const scrollViewLayout = ref({ left: 0, width: 0 })

		//scroll-view滑动距离
		const scrollViewSlideDistance = computed(() => {
			try {
				return (blockSlideDistance.value - scrollViewLayout.value.width / 2) + (currentBlockWidth.value / 2)
			} catch (e) {
				return 0
			}
		})

		//当外部的下标值改变时，同步更新下标
		watch(() => props.modelValue, v => {
			if (v != currentIndex.value) currentIndex.value = v
		}, { immediate: true })

		// 挂在后执行操作
		onMounted(() => {
			//当外部列表更新时，重新初始化
			watch(() => props.list, async (newVal, oldVal) => {
				//如果列表为空，不执行初始化
				if (!newVal.length && newVal == oldVal) return
				await init()
			}, { immediate: true, deep: true })
		})

		//初始化布局信息
		async function init() {
			const query = uni.createSelectorQuery().in(ctx);
			//获取scrollView的布局信息
			scrollViewLayout.value = await new Promise(resolve => {
				query.select(`#scroll-view${uid}`)
					.boundingClientRect(layout => resolve({ width: layout?.width, left: layout?.left }))
					.exec()
			})
			getItemWidthEvent()
			
		}
		
		async function getItemWidthEvent(){
			const query = uni.createSelectorQuery().in(ctx);
			// 获取滑块条的尺寸信息
			blockList.value = await new Promise(resolve => {
				//获取所有滑块的宽度
				query.selectAll(`.block-item`)
					.boundingClientRect(layout => resolve(layout.map(({ width, left }) => ({ width, left }))))
					.exec()
			})
			newBlockList.value = await new Promise(resolve => {
				//获取所有滑块的宽度
				query.selectAll(`.new-block-item`)
					.boundingClientRect(layout => resolve(layout.map(({ width, left }) => ({ width, left }))))
					.exec()
			})
			console.log(blockList.value, '初始宽度')
			console.log(newBlockList.value, '初始选中的宽度')
		}

		//点击时
		async function clickBlockEvent(e) {
			currentIndex.value = e
			emit('update:modelValue', e)
			emit('changeEvent', e)
		}

		return { currentIndex, currentBlockWidth, clickBlockEvent, blockSlideDistance, scrollViewSlideDistance }
	}
</script>

<style lang="scss">
.tabbox{height: pxs(62); line-height: pxs(62)}
.tabbox .item{font-size: pxs(24); color: #162738;  padding:0 pxs(35); flex: 1; text-align: center}
.tabbox .item.actived{color: #FFAE00}
.tabbox .slider{width: calc(100% - pxs(70)); height: pxs(5); background-color: #FFAE00; position: absolute; left: pxs(35)}
.tabbox .item.scroll{display: inline-block}
</style>
